package controleur;

import beans.Graphe;
import beans.Equipe;
import beans.Etudiant;
import beans.Formateur;
import beans.Module;
import beans.Projet;
import beans.User;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.sql.Date;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import modele.ProjetGantt;
import modele.dao.AuthentificationDAO;
import modele.dao.GestionProjetDAO;
import modele.dao.UserDAO;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.servlet.ServletUtilities;

/**
 * Le controleur ( HttpServlet ) de l'application AGP
 * @author Rami & Amanda
 */
public class Controleur extends HttpServlet {

    int id_projet;
    String nom;
    String description;
    int promotion;
    Date debut;
    Date fin;
    int nbFormateurs;
    int nbModules;
    int nbEquipes;
    int nbMembres;

    /**
     * processRequest : Analyse les requêtes HTTP (méthodes POST et GET)
     * @param request Servlet request
     * @param response Servlet response
     * @throws ServletException Servlet erreur
     * @throws IOException I/O erreur
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String idaction = null;
        request.setAttribute("url", null);
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        
        try {
            String forward = "erreur.jsp";
            if (idaction == null) {
                idaction = request.getParameter("action");
            }
            if (idaction.equals("Lancer la recherche")) {
                forward = LancerServiceRechercher(request);
            } else if (idaction.equals("M1 Initiale et continue")) {    // Menu : Recherche des projets de M1 FIC
                forward = LancerServiceRechercherParPromo(request, 1);
            } else if (idaction.equals("M1 Apprentissage")) {           // Menu : Recherche des projets de M1 FA
                forward = LancerServiceRechercherParPromo(request, 2);
            } else if (idaction.equals("M2 Initiale et continue")) {    // Menu : Recherche des projets de M2 FIC
                forward = LancerServiceRechercherParPromo(request, 3);
            } else if (idaction.equals("M2 Apprentissage")) {           // Menu : Recherche des projets de M2 FA
                forward = LancerServiceRechercherParPromo(request, 4);
            } else if (idaction.equals("Rechercher")) {                 // Action : Rechercher un projet
                forward = LancerServiceRechercherParPromo(request, 0);
            } else if (idaction.equals("Suivant")) {                    // Action : Creation d'un projet
                forward = LancerServiceCreationProjet(request);
            } else if (idaction.equals("Enregistrer")) {                // Action : Creation des details du projet
                forward = LancerServiceCreationEquipes(request);
            } else if (idaction.equals("AfficherProjet")) {             // Action : Afficher les details du projet
                forward = LancerServiceAffichageProjet(request);
            } else if (idaction.equals("Mes Projets")) {                // Menu : Recherche des projets du User
                forward = LancerServiceRechercheMesProjets(request);
            } else if (idaction.equals("Creer")) {                      // Menu : Creer un nouveau projet
                forward = "creation.jsp";
            } else if (idaction.equals("Supprimer")) {                  // Action : Supprimer un projet
                forward = LancerServiceSupprimer(request);
            } else if (idaction.equals("Connection")) {                 // Action : Connecter a l'application
                forward = LancerServiceConnection(request);
            } else if (idaction.equals("Modifier")) {                   // Action : Modifier le projet selectionne
                forward = LancerPageModifier(request);
            } else if (idaction.equals("Valider")) {                    // Action : Enregistrer les modification du projet
                forward = LancerServiceModifier(request);
            } else if (idaction.equals("Accueil")) {                    // Banniere : Lien vers la page principale
                forward = "index.jsp";
            } else if (idaction.equals("Quitter")) {                    // Banniere : Lien vers la page d'authentification
                forward = "authentification.jsp";
            }
            RequestDispatcher dispatcher = request.getRequestDispatcher(forward);
            dispatcher.forward(request, response);
        } catch (Exception e) {
            request.setAttribute("e", e);
            RequestDispatcher dispatcher = request.getRequestDispatcher("erreurModele.jsp");
            dispatcher.forward(request, response);
        } finally {
            out.close();
        }
    }

    /**
     * LancerServiceRechercher : Méthode du controleur permettant le lancement de la recherche d'un projet
     * @param request Requête HTTP fournie
     * @return nom de la vue à construire
     * @throws Exception
     */
    private String LancerServiceRechercher(HttpServletRequest request) throws Exception {
        String forward;
        ArrayList<Projet> resultat;
        int idModule = Integer.parseInt(request.getParameter("idModule"));
        int idpromotion = Integer.parseInt(request.getParameter("promotion"));
        int idFormateur = Integer.parseInt(request.getParameter("idFormateur"));
        resultat = GestionProjetDAO.rechercher(idpromotion, idModule, idFormateur);
        forward = "recherche.jsp";
        request.setAttribute("listeResultat", resultat);
        int taille = resultat.size();
        int hauteur;
        hauteur = tailleImage(taille);
        Graphe graphe = fabriquerGraphe(resultat, request, hauteur);
        request.setAttribute("graphe", graphe);

        return forward;
    }

    /**
     * LancerServiceRechercherParPromo : Méthode du controleur permettant le lancement de la recherche par promotion
     * @param request Requête HTTP fournie
     * @param action Promotion demandée
     * @return nom de la vue à construire
     * @throws Exception
     */
    private String LancerServiceRechercherParPromo(HttpServletRequest request, int action) throws Exception {
        String forward;
        ArrayList<Projet> resultat;
        resultat = GestionProjetDAO.rechercher(action, 0, 0);
        forward = "recherche.jsp";
        request.setAttribute("listeResultat", resultat);
        int taille = resultat.size();
        int hauteur;
        hauteur = tailleImage(taille);
        Graphe graphe = fabriquerGraphe(resultat, request, hauteur);
        request.setAttribute("graphe", graphe);

        return forward;
    }

    /**
     * LancerServiceAffichageProjet : Méthode du controleur permettant le lancement de l'affichage des détails d'un projet
     * @param request Requête HTTP fournie
     * @return nom de la vue à construire
     * @throws Exception
     */
    private String LancerServiceAffichageProjet(HttpServletRequest request) throws Exception {
        String forward;
        Projet resultat;
       
         int   id = Integer.parseInt(request.getParameter("id_Projet"));
      
        resultat = GestionProjetDAO.rechercherDetailProjet(id);
        forward = "detailProjet.jsp";
        request.setAttribute("detailProjet", resultat);

        return forward;
    }

    /**
     * LancerServiceCreationProjet : Méthode du controleur permettant le lancement de la création d'un projet
     * @param request Requête HTTP fournie
     * @return nom de la vue à construire
     * @throws Exception
     */
    private String LancerServiceCreationProjet(HttpServletRequest request) throws Exception {
        nom = request.getParameter("nomProjet");
        String dateDebut = request.getParameter("dateDebut");
        String dateFin = request.getParameter("dateFin");
        description = request.getParameter("descriptionProjet");
        String controle = Outils.controlerFormulaireCreationProjet(nom, dateDebut, dateFin, description);

        if (controle.equals("")) {
            debut = Date.valueOf(dateDebut);
            fin = Date.valueOf(dateFin);
            promotion = Integer.parseInt(request.getParameter("promotion"));
            nbFormateurs = Integer.parseInt(request.getParameter("nbFormateurs"));
            nbModules = Integer.parseInt(request.getParameter("nbModules"));
            nbEquipes = Integer.parseInt(request.getParameter("nbEquipes"));
            nbMembres = Integer.parseInt(request.getParameter("nbMembres"));
            request.setAttribute("nbFormateurs", nbFormateurs);
            request.setAttribute("nbModules", nbModules);
            request.setAttribute("nbEquipes", nbEquipes);
            request.setAttribute("nbMembres", nbMembres);
            return "creation2.jsp";
        } else {
            request.setAttribute("controle", controle);
            return "creation.jsp";
        }
    }

    /**
     * LancerServiceCreationEquipes : Méthode du controleur permettant le lancement de la création des équipes d'un projet
     * @param request Requête HTTP fournie
     * @return nom de la vue à construire
     * @throws Exception
     */
    public String LancerServiceCreationEquipes(HttpServletRequest request) throws Exception {
        String resultat;
        String forward = "erreur.jsp";
        ArrayList<Formateur> listeFormateurs = new ArrayList<Formateur>();
        ArrayList<Module> listeModules = new ArrayList<Module>();
        ArrayList<Equipe> listeEquipes = new ArrayList<Equipe>();

        for (int i = 0; i < nbFormateurs; i++) {
            listeFormateurs.add(new Formateur(Integer.parseInt(request.getParameter("idFormateur" + i))));
        }
        for (int i = 0; i < nbModules; i++) {
            listeModules.add(new Module(Integer.parseInt(request.getParameter("idModule" + i))));
        }
        for (int i = 0; i < nbEquipes; i++) {
            ArrayList<Etudiant> etudiants = new ArrayList<Etudiant>();
            for (int y = 0; y < nbMembres; y++) {
                etudiants.add(new Etudiant(Integer.parseInt(request.getParameter("idEtudiant" + i + "-" + y))));
            }
            Equipe e = new Equipe(etudiants);
            listeEquipes.add(e);
        }
        String controle = Outils.controlerListesSelectionnees(listeModules, listeFormateurs, listeEquipes);
        if (controle.equals("")) {
            resultat = GestionProjetDAO.creerProjet(nom, description, debut, fin, listeModules, listeFormateurs, listeEquipes, promotion);
            forward = "detailProjet.jsp";
            request.setAttribute("detailProjet", GestionProjetDAO.rechercherDetailProjet(Integer.parseInt(resultat)));
            java.util.Date d = new java.util.Date();
            User u = (User) request.getSession().getAttribute("user");
            StringBuffer log = (StringBuffer) getServletContext().getAttribute("log");

            log.insert(0,"[" + d.getDate() + "/" + (d.getMonth() + 1) + "/" + (d.getYear() + 1900) + " " + d.getHours() + ":" + d.getMinutes() + "] Le projet " + nom + " à été crée par " + u.getPrenom() + " " + u.getNom() + ".<br>");
            getServletContext().setAttribute("log", log);
            return forward;
        } else {
            request.setAttribute("controle", controle);
            request.setAttribute("nbFormateurs", nbFormateurs);
            request.setAttribute("nbModules", nbModules);
            request.setAttribute("nbEquipes", nbEquipes);
            request.setAttribute("nbMembres", nbMembres);
            return "creation2.jsp";
        }
    }

    /**
     * LancerServiceSupprimer : Méthode du controleur permettant le lancement de la suppression d'un projet
     * @param request Requête HTTP fournie
     * @return nom de la vue à construire
     * @throws Exception
     */
    private String LancerServiceSupprimer(HttpServletRequest request) throws Exception {
        String forward;
        String resultat;
        int id = Integer.parseInt(request.getParameter("numero"));
        resultat = GestionProjetDAO.supprimerProjet(id);
        forward = "index.jsp";
        java.util.Date d = new java.util.Date();
        User u = (User) request.getSession().getAttribute("user");
        StringBuffer log = (StringBuffer) getServletContext().getAttribute("log");
        log.insert(0,"[" + d.getDate() + "/" + (d.getMonth() + 1) + "/" + (d.getYear() + 1900) + " " + d.getHours() + ":" + d.getMinutes() + "] Le projet numéro " + id + " à été supprimé par " + u.getPrenom() + " " + u.getNom() + ".<br>");
        getServletContext().setAttribute("log", log);
        return forward;
    }

    /**
     * LancerPageModifier :  Méthode du controleur permettant le lancement de la page de modification d'un projet
     * @param request Requête HTTP fournie
     * @return nom de la vue à construire
     * @throws Exception
     */
    private String LancerPageModifier(HttpServletRequest request) throws Exception {
        String forward;
        Projet resultat;
        int id = Integer.parseInt(request.getParameter("numero"));
        resultat = GestionProjetDAO.rechercherDetailProjet(id);
        if (resultat != null) {
            forward = "modifProjet.jsp";
            request.setAttribute("detailProjet", resultat);
        } else {
            forward = "error.jsp";
        }

        return forward;
    }

    /**
     * LancerServiceModifier :  Méthode du controleur permettant le lancement de la modification d'un projet
     * @param request Requête HTTP fournie
     * @return nom de la vue à construire
     * @throws Exception
     */
    public String LancerServiceModifier(HttpServletRequest request) throws Exception {
        int id = Integer.parseInt(request.getParameter("numero"));
        Projet ancienProjet = GestionProjetDAO.rechercherDetailProjet(id);
        String dateDebut = request.getParameter("dateDebut");
        String dateFin = request.getParameter("dateFin");
        String nouveauNom = request.getParameter("nomProjet") ;
        String nouvelleDescription = request.getParameter("descriptionProjet");
        int nouvellePromotion = Integer.parseInt(request.getParameter("promotion"));

        String resultat;
        ArrayList<Formateur> nouvelleListeFormateurs = new ArrayList<Formateur>();
        ArrayList<Module> nouvelleListeModules = new ArrayList<Module>();
        ArrayList<Equipe> nouvelleListeEquipes = new ArrayList<Equipe>();
       

        for (int i = 0; i < ancienProjet.getFormateurs().size(); i++) {
            nouvelleListeFormateurs.add(new Formateur(Integer.parseInt(request.getParameter("idFormateur" + i))));
        }
        for (int i = 0; i < ancienProjet.getModules().size(); i++) {
            nouvelleListeModules.add(new Module(Integer.parseInt(request.getParameter("idModule" + i))));
        }
        for (int i = 0; i < ancienProjet.getEquipes().size(); i++) {
            ArrayList<Etudiant> etudiants = new ArrayList<Etudiant>();
            for (int y = 0; y < ancienProjet.getEquipes().get(i).getEtudiants().size(); y++) {
                etudiants.add(new Etudiant(Integer.parseInt(request.getParameter("idEtudiant" + i + "-" + y))));
            }
            Equipe e = new Equipe(etudiants);

            nouvelleListeEquipes.add(e);
        }

        

        String controle = Outils.controlerFormulaireModifer(nouveauNom, dateDebut, dateFin, nouvelleDescription, nouvelleListeModules, nouvelleListeFormateurs, nouvelleListeEquipes);
         if (controle.equals("")) {
          ancienProjet.setNom(nouveauNom);
        ancienProjet.setDescriptif(nouvelleDescription);
        ancienProjet.setPromotion(nouvellePromotion);
        ancienProjet.setDateDebut(Date.valueOf(dateDebut));
        ancienProjet.setDateFin(Date.valueOf(dateFin));
        ancienProjet.setEquipes(nouvelleListeEquipes);
        ancienProjet.setModules(nouvelleListeModules);
        ancienProjet.setFormateurs(nouvelleListeFormateurs);
        resultat = GestionProjetDAO.modifierProjet(ancienProjet);
        request.setAttribute("detailProjet", GestionProjetDAO.rechercherDetailProjet(Integer.parseInt(resultat)));
        java.util.Date d = new java.util.Date();
        User u = (User) request.getSession().getAttribute("user");
        StringBuffer log = (StringBuffer) getServletContext().getAttribute("log");
        log.insert(0,"[" + d.getDate() + "/" + (d.getMonth() + 1) + "/" + (d.getYear() + 1900) + " " + d.getHours() + ":" + d.getMinutes() + "] Le projet " + ancienProjet.getNom() + " à été modifié par " + u.getPrenom() + " " + u.getNom() + ".<br>");
        getServletContext().setAttribute("log", log);
        return "detailProjet.jsp";

        }else {

        request.setAttribute("controle", controle);
        request.setAttribute("detailProjet", ancienProjet);
            return "modifProjet.jsp";
        }
    }

    /**
     * LancerServiceConnection : Méthode du controleur permettant le lancement de la connection
     * @param request Requête HTTP fournie
     * @return nom de la vue à construire
     * @throws Exception
     */
    private String LancerServiceConnection(HttpServletRequest request) throws Exception {
        String login = request.getParameter("login");
        String pwd = request.getParameter("pwd");
        int id = AuthentificationDAO.authentification(login, pwd);
        if (id == 0) {
            return "authentification.jsp";
        } else {
            User u = UserDAO.rechercherUser(id);
            if (u.isIsAdmin()) {
                request.getSession().setAttribute("isAdmin", true);
                request.getSession().setAttribute("user", u);
                java.util.Date d = new java.util.Date();
                StringBuffer log = (StringBuffer) getServletContext().getAttribute("log");
                log.insert(0,"[" + d.getDate() + "/" + (d.getMonth() + 1) + "/" + (d.getYear() + 1900) + " " + d.getHours() + ":" + d.getMinutes() + "] L'administrateur " + u.getPrenom() + " " + u.getNom() + " s'est connecté.<br>");
                getServletContext().setAttribute("log", log);
                return "index.jsp";
            } else if (!u.isIsAdmin()) {
                request.getSession().setAttribute("isAdmin", false);
                request.getSession().setAttribute("user", u);
                java.util.Date d = new java.util.Date();
                StringBuffer log = (StringBuffer) getServletContext().getAttribute("log");
                log.insert(0,"[" + d.getDate() + "/" + (d.getMonth() + 1) + "/" + (d.getYear() + 1900) + " " + d.getHours() + ":" + d.getMinutes() + "] L'utilisateur " + u.getPrenom() + " " + u.getNom() + " s'est connecté.<br>");
                getServletContext().setAttribute("log", log);
                return "index.jsp";
            }
            return "authentification.jsp";
        }
    }

    /**
     * LancerServiceRechercheMesProjets : Méthode du controleur permettant le lancement de la recherche des projet de l'utilisateur
     * @param request Requête HTTP fournie
     * @return nom de la vue à construire
     * @throws Exception
     */
    private String LancerServiceRechercheMesProjets(HttpServletRequest request) throws Exception {
        String forward;
        ArrayList<Projet> resultat;
        User u = (User) request.getSession().getAttribute("user");
        if (u.isIsAdmin()) {
            resultat = GestionProjetDAO.rechercher(0, 0, u.getId());
        } else {
            resultat = GestionProjetDAO.rechercherMesProjetsEtudiants(u.getId());
        }
        forward = "recherche.jsp";
        request.setAttribute("listeResultat", resultat);
        int taille = resultat.size();
        int hauteur;
        hauteur = tailleImage(taille);
        Graphe graphe = fabriquerGraphe(resultat, request, hauteur);
        request.setAttribute("graphe", graphe);
        return forward;
    }

    /**
     * initImage : Méthode du controleur permettant l'initialisation de l'image du graphe
     * @param request Requête HTTP fournie
     * @return Graphe
     */
    private Graphe initImage(HttpServletRequest request, ChartRenderingInfo chartRenderingInfo, String filename) {
        String map = ChartUtilities.getImageMap(filename, chartRenderingInfo);
        String src = request.getContextPath() + "/servlet/DisplayChart?filename=" + filename;
        String useMap = "#" + filename;
        Graphe graphe = new Graphe();
        graphe.setGraphe(map);
        graphe.setSource(src);
        graphe.setUtilisationGraphe(useMap);

        return graphe;
    }

    /**
     * tailleImage : Méthode interne permettant de definir la taille de l'image du graphe
     * @param taille Nombre de projets à afficher
     * @return hauteur
     */
    private int tailleImage(int taille) {
        int hauteur = 150 + (40 * taille);
        return hauteur;
    }

    /**
     * fabriquerGraphe : Méthode du controleur permettant la création de l'image du graphe
     * @param request Requête HTTP fournie
     * @param resultat Liste des projets à afficher
     * @param  hauteur Hauteur du graphe adéquate
     * @return Graphe
     * @throws IOException
     */
    private Graphe fabriquerGraphe(ArrayList<Projet> resultat, HttpServletRequest request, int hauteur) throws IOException {
        ProjetGantt pg = new ProjetGantt(resultat);
        ChartRenderingInfo chartRenderingInfo = new ChartRenderingInfo(new StandardEntityCollection());
        String filename = ServletUtilities.saveChartAsJPEG(pg.getModele(), 600, hauteur, chartRenderingInfo, request.getSession());
        Graphe graphe = this.initImage(request, chartRenderingInfo, filename);
        return graphe;
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }
    // </editor-fold>
}
